﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Diagnostics;
using System.Windows.Markup;

namespace Xceed.Silverlight.Data
{
  [DebuggerDisplay( "FilterBy = {DebuggerDisplayString}" )]
  [ContentProperty( "ChildExpression" )]
  public sealed class NotFilterExpression : FilterExpressionBase
  {
    #region Constructors

    public NotFilterExpression( FilterExpressionBase expression )
    {
      if( expression == null )
        throw new ArgumentNullException( "expression" );

      m_childExpression = expression;
    }

    public NotFilterExpression()
    {
      //CTOR added to make this class XAML-able.
    }

    #endregion

    #region ChildExpression Property

    public FilterExpressionBase ChildExpression
    {
      get
      {
        return m_childExpression;
      }
      set
      {
        if( this.IsFrozen )
          throw new InvalidOperationException( "An attempt was made to modify the value while the NotFilterExpression is frozen." );

        if( value != m_childExpression )
        {
          m_childExpression = value;
        }
      }
    }

    private FilterExpressionBase m_childExpression;

    #endregion

    public override int GetHashCode()
    {
#if WINDOWS_PHONE
      this.Freeze();
#endif

      if( m_childExpression == null )
        return 0;

      return m_childExpression.GetHashCode();
    }

    public override bool Equals( object obj )
    {
#if WINDOWS_PHONE
      this.Freeze();
#endif

      if( object.ReferenceEquals( this, obj ) )
        return true;

      NotFilterExpression expression = obj as NotFilterExpression;
      if( expression == null )
        return false;

      if( expression.GetHashCode() != this.GetHashCode() )
        return false;

      return object.Equals( expression.ChildExpression, this.ChildExpression );
    }

    internal override FilterExpressionBase Clone()
    {
#if WINDOWS_PHONE
      this.Freeze();
#endif

      if( m_childExpression == null )
        throw new InvalidOperationException( "An attempt was made to clone a filter expression that does not have a child expression." );

      FilterExpressionBase child = m_childExpression.Clone();

      return new NotFilterExpression( child );
    }

    [DebuggerStepThrough]
    internal override void Accept( FilterExpressionVisitor visitor )
    {
#if WINDOWS_PHONE
      this.Freeze();
#endif

      if( visitor != null )
      {
        visitor.Visit( this );
      }
    }

    internal override void FreezeOverride()
    {
      if( m_childExpression == null )
        throw new InvalidOperationException( "An attempt was made to freeze a filter expression that does not have a child expression." );

      m_childExpression.Freeze();

      base.FreezeOverride();
    }
  }
}
